var http = require('http');
var redis = require('redis');
var mysql = require('mysql');
var url = require('url');
var querystring = require('querystring');
var getIpFromHosts = require('./getIpFromHosts.js');

var cfg = {
	"lookup": {
		"hostname_redis": "redis.host",
		"hostname_mysql": "mysql.host",
		"www.google.com": "test.host",
		"NODE_ENV": "test.env"
	},
	"mysql": {
		"host": 'localhost',
		"port": 3306,
		"user": 'root',
		"database": 'o2o',
		"password": 'mysql'
	},
	"redis": {
		"host": "127.0.0.1",
		"port": "6379"
	},
	"test": {
		"host": "127.0.0.1",
		"env": "aaa"
	}
};

var __mysqlConn;
var __redisCli;



function setupEnv() {
	console.log(' [x] setupEnv');
	var count = 0;
	var replaceCnt = 0;
	var keys = Object.keys(cfg.lookup);
	var len = keys.length;

	function next(fulfil) {
		// console.log(' [x] next count=%d', count);
		if (count === keys.length) {
			// TODO
			fulfil();
			return;
		} else {
			var key = keys[count];
			__setUpOneKey(key)

			.then(function(isOk) {
				console.log(' [x] set up %s done', key);
				count += 1;
				replaceCnt += isOk;
				next(fulfil);
			});
		}
	}


	return new Promise(function(fulfil, reject) {
		next(fulfil);
	});
}

function __setUpOneKey(key) {
	return new Promise(function(fulfil, reject) {
		// console.log(" [x] lookup %s", key);
		if (process.env[key]) {
			console.log(" [x] found %s in process.env , value = %s", key, process.env[key]);
			var path = cfg.lookup[key].split('.');
			__replaceCfgValue(path, process.env[key]);
			fulfil(1);

		} else {
			getIpFromHosts.getIp2(key)

			.then(function(res) {
				if (res.ip) {
					console.log(" [x] found %s = %s , in /etc/hosts ", key, res.ip);
					__replaceCfgValue(cfg.lookup[key].split('.'), res.ip);
					fulfil(1);
				} else {
					console.log(" [x] not found  %s", key);
					fulfil(0);
				}
			});
		}
	});
}

function __replaceCfgValue(path, value) {
	console.log(' [x] __replaceCfgValue [%s]=%s', path.join('.'), value);
	var target = cfg;
	var last = path.length - 1;
	for (var i = 0; i < last; i++) {
		target = target[path[i]];
	}
	var key = path[last];
	target[key] = value;
}

function __prepareMysql() {
	return new Promise(function(fulfil, reject) {
		__mysqlConn = mysql.createConnection(cfg.mysql);
		__mysqlConn.connect(function(err) {
			if (err) return reject('mysql connect err');
			console.log('connect mysql ok');
			fulfil();
		})
	});
}

function __mysqlQuery() {
	var sql = "select id,name,author,price from books limit 1";
	return new Promise(function(fulfil, reject) {
		__mysqlConn.query(sql, function(err, rows, fields) {
			if (err) return reject('mysql error' + err);
			var list = [];
			rows.forEach(function(item) {
				var obj = {
					id: item.id,
					name: item.name,
					author: item.author,
					price: item.price
				};
				list.push(obj);
			});
			console.log('from mysql, book=' + JSON.stringify(list[0]));
			fulfil(list);
		});
	});
}

function __redisSave(book) {
	console.log('__redisSave', book);
	return new Promise(function(fulfil, reject) {
		__redisCli.hmset('book:' + book.id, "json", JSON.stringify(book), function(err) {
			if (err) return reject('redis save err:' + err);
			console.log('redis save done');
			fulfil(book);
		});
	});
}


function __httpHandler(req, res) {
	console.log('receive request');
	__mysqlQuery()

	.then(function(books) {
		var book = books[0];
		res.end(JSON.stringify(book) + '\n');
		return __redisSave(book);
	})

	.then(function(book) {
		console.log('all done');
	})

	.catch(function(err) {
		console.log(err);
	})
}


function main() {
	setupEnv()

	.then(function() {
		console.log(' [x] setupEnv done');
		delete cfg.lookup;
		! function() {
			console.log('-----------------env-----------');
			console.log(cfg);
		}();

		return __prepareMysql();
	})

	.then(function prepareRedis() {
		__redisCli = redis.createClient(cfg.redis.port, cfg.redis.host);
		console.log('connect redis ok');
	})

	.then(function prepareHttpServer() {
		var server = http.createServer(__httpHandler);
		console.log('server listen on 5001');
		server.listen(5001);
	})

	.then(function startServer(server) {})

	.catch(function(err) {
		console.log(err);
	});
}


main();